package com.vasthu.gui;

import com.vasthu.api.domain.Item;
import com.vasthu.api.domain.Stock;
import com.vasthu.api.service.ItemManagerService;
import com.vasthu.api.service.StockManagerService;
import com.vasthu.core.service.ItemManagerServiceImpl;
import com.vasthu.core.service.StockManagerServiceImpl;
import com.vasthu.gui.utility.SpringUtilities;
import com.vasthu.gui.utility.VstGuiUtils;
import com.vasthu.utility.DateTimeUtils;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.text.*;

public class VstStockDataForm extends JDialog {

	private long stockId;
    private JLabel lStockTitle;
    private JLabel lSearchCode;
	private JTextField tSearchCode;
	private JButton addThis;
	private JButton advanceSearch;
    
	private JLabel liCode;
	private JLabel liName;
	private JLabel liBrand;
	private JLabel liCategory;
	private JLabel tiCode;
	private JLabel tiName;
	private JLabel tiBrand;
	private JLabel tiCategory;
	
	private JLabel lQty;
	private JLabel lDiscount;
	private JLabel lunitPrice;
	private JLabel lminPrice;
	private JLabel lmaxPrice;
	private JFormattedTextField tQty;
	private JSpinner tDiscount;
	private JSpinner tunitPrice;
	private JSpinner tminPrice;
	private JSpinner tmaxPrice;
	
	private JLabel lDispatchDate;
	private JComboBox dtYear;
	private JComboBox dtMonth;
	private JComboBox dtDate;
	
	private JLabel lExpDate;
	private JComboBox xtYear;
	private JComboBox xtMonth;
	private JComboBox xtDate;
	
	private JButton addStock;
	private JButton updateStock;
	private JButton deleteStock;
	private JButton cancel;

	private int mode;
	private int tableRow;
	private VstTableCallBack callback;
	private long currentStockId;
	
	private long selectedItemId;

	private ItemManagerService itemManagerService = null;
	private StockManagerService stockManagerService = null;
	
	public VstStockDataForm(int mode, int tableRow, VstTableCallBack callback) {
		
		itemManagerService = new ItemManagerServiceImpl();
		stockManagerService = new StockManagerServiceImpl();
		selectedItemId = -1;
		
        initUi();
		initActions();
		this.tableRow = tableRow;
		this.callback = callback;
		currentStockId = -1;
		
		switch(mode) {
			case VstGuiConstants.STOCK_FORM_ADD:
				addStock.setVisible(true);
                updateStock.setVisible(false);
                deleteStock.setVisible(false);
				//spacer.setVisible(false);
				break;
			case VstGuiConstants.STOCK_FORM_UPDATE:
				addStock.setVisible(false);
                updateStock.setVisible(true);
                deleteStock.setVisible(true);
				//spacer.setVisible(true);
				break;
			default:
				break;
		}
		
    }
	
	private void initUi() {
		lStockTitle = new JLabel("Stock", JLabel.CENTER);
        lStockTitle.setFont(new Font("Monospaced 12", Font.BOLD, 16));
		
		liCode = new JLabel("Code : ", JLabel.TRAILING);
        liCode.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		liName = new JLabel("Name : ", JLabel.TRAILING);
        liName.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		liBrand = new JLabel("Brand : ", JLabel.TRAILING);
        liBrand.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		liCategory = new JLabel("Category : ", JLabel.TRAILING);
        liCategory.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		
		tiCode = new JLabel("---", JLabel.LEADING);
		tiCode.setForeground(Color.BLUE);
		tiCode.setPreferredSize(new Dimension(Integer.MAX_VALUE, 20));
        tiCode.setMaximumSize(new Dimension(Integer.MAX_VALUE, 20));
		tiName = new JLabel("---", JLabel.LEADING);
		tiName.setForeground(Color.BLUE);
		tiName.setPreferredSize(new Dimension(Integer.MAX_VALUE, 20));
        tiName.setMaximumSize(new Dimension(Integer.MAX_VALUE, 20));
		tiBrand = new JLabel("---", JLabel.LEADING);
		tiBrand.setForeground(Color.BLUE);
		tiBrand.setPreferredSize(new Dimension(Integer.MAX_VALUE, 20));
        tiBrand.setMaximumSize(new Dimension(Integer.MAX_VALUE, 20));
		tiCategory = new JLabel("---", JLabel.LEADING);
		tiCategory.setForeground(Color.BLUE);
		tiCategory.setPreferredSize(new Dimension(Integer.MAX_VALUE, 20));
        tiCategory.setMaximumSize(new Dimension(Integer.MAX_VALUE, 20));
		
		lSearchCode = new JLabel("Search Code : ", JLabel.TRAILING);
        lSearchCode.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		tSearchCode = new JTextField();
		tSearchCode.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        tSearchCode.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		addThis = new JButton("Add This");
		advanceSearch = new JButton("Advanced Search");
		
		JPanel searchPanel = new JPanel(new SpringLayout());
		
		searchPanel.add(lSearchCode);
		searchPanel.add(tSearchCode);
		searchPanel.add(addThis);
		searchPanel.add(advanceSearch);
		
		SpringUtilities.makeCompactGrid(searchPanel,
                1, 4, //rows, cols
                8, 8, //initialX, initialY
                8, 0);
		
		JPanel leftPanel = new JPanel(new SpringLayout());
		JPanel rightPanel = new JPanel(new SpringLayout());
		
		leftPanel.add(liCode);
		leftPanel.add(tiCode);
		leftPanel.add(liName);
		leftPanel.add(tiName);
		
		rightPanel.add(liBrand);
		rightPanel.add(tiBrand);
		rightPanel.add(liCategory);
		rightPanel.add(tiCategory);
		
		SpringUtilities.makeCompactGrid(leftPanel,
                2, 2, //rows, cols
                8, 0, //initialX, initialY
                8, 0);
				
		SpringUtilities.makeCompactGrid(rightPanel,
                2, 2, //rows, cols
                8, 0, //initialX, initialY
                8, 0);
		
		JPanel iPanel = new JPanel(new GridLayout(1, 2));
		iPanel.setBorder(new TitledBorder("Item Details"));
		
		iPanel.add(leftPanel);
		iPanel.add(rightPanel);
		
		iPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 80));
        iPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 80));
		
		JPanel dataPanel = new JPanel(new SpringLayout());
		lQty = new JLabel("Quentity : ", JLabel.TRAILING);
        lQty.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		
		NumberFormat salaryFormat = new DecimalFormat("###,###,###.00");
        tQty = new JFormattedTextField(salaryFormat);
        tQty.setPreferredSize(new Dimension(130, 25));
        tQty.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		
		Float dstep = new Float(0.01);
		Float minDiscount = new Float(0.00);
		Float maxDiscount = new Float(100.00);
		Float currentDiscount = new Float(0.00);

		lDiscount = new JLabel("Discount : ", JLabel.TRAILING);
        lDiscount.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		tDiscount = new JSpinner(new SpinnerNumberModel(currentDiscount, minDiscount, maxDiscount, dstep) );
		tDiscount.setPreferredSize(new Dimension(130, 25));
        tDiscount.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		
		Float step = new Float(0.25);
		Float min = new Float(0.00);
		Float max = new Float(99999999.99);
		Float value = new Float(0.00);
		
		tunitPrice = new JSpinner(new SpinnerNumberModel(value, min, max, step) );
		tunitPrice.setPreferredSize(new Dimension(80, 25));
        tunitPrice.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		tminPrice = new JSpinner(new SpinnerNumberModel(value, min, max, step) );
		tminPrice.setPreferredSize(new Dimension(80, 25));
        tminPrice.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		tmaxPrice = new JSpinner(new SpinnerNumberModel(value, min, max, step) );
		tmaxPrice.setPreferredSize(new Dimension(80, 25));
        tmaxPrice.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		lunitPrice = new JLabel("Unit Price : ", JLabel.TRAILING);
		lunitPrice.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		lminPrice = new JLabel("Min Price : ", JLabel.TRAILING);
		lminPrice.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		lmaxPrice = new JLabel("Max Price : ", JLabel.TRAILING);
		lmaxPrice.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		
		JPanel pricePanel = new JPanel();
		pricePanel.setLayout(new BoxLayout(pricePanel, BoxLayout.X_AXIS));
		pricePanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        pricePanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		
		pricePanel.add(tunitPrice);
		pricePanel.add(Box.createRigidArea(new Dimension(20, 10)));
		pricePanel.add(lminPrice);
		pricePanel.add(Box.createRigidArea(new Dimension(10, 10)));
		pricePanel.add(tminPrice);
		pricePanel.add(Box.createRigidArea(new Dimension(20, 10)));
		pricePanel.add(lmaxPrice);
		pricePanel.add(Box.createRigidArea(new Dimension(10, 10)));
		pricePanel.add(tmaxPrice);
		
		JPanel qtyPanel = new JPanel();
		qtyPanel.setLayout(new BoxLayout(qtyPanel, BoxLayout.X_AXIS));
		qtyPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 25));
        qtyPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
		
		qtyPanel.add(tQty);
		qtyPanel.add(Box.createRigidArea(new Dimension(20, 10)));
		qtyPanel.add(lDiscount);
		qtyPanel.add(tDiscount);
		
		dataPanel.add(lQty);
		dataPanel.add(qtyPanel);
		dataPanel.add(lunitPrice);
		dataPanel.add(pricePanel);
				
		// start dispatch date
		dtYear = new JComboBox();
		dtYear.setPreferredSize(new Dimension(100, 25));
        dtYear.setMaximumSize(new Dimension(100, 25));
		dtMonth = new JComboBox(new DateFormatSymbols().getMonths());
		dtMonth.removeItem("");
		dtMonth.setPreferredSize(new Dimension(100, 25));
        dtMonth.setMaximumSize(new Dimension(100, 25));
		dtDate = new JComboBox();
		dtDate.setPreferredSize(new Dimension(80, 25));
        dtDate.setMaximumSize(new Dimension(80, 25));
		
		int year = Calendar.getInstance().get(Calendar.YEAR);
		for (int i = 1930; i <= year; i++)
			dtYear.addItem(String.valueOf(i));
		
		dtMonth.addActionListener(new ActionListener() {
			@Override
            public void actionPerformed(ActionEvent e) {
				String year = (String)dtYear.getSelectedItem();
                String month = (String)dtMonth.getSelectedItem();
				int maxDate = VstGuiUtils.getMaxDateForYearAndMonth(year, month);
				
				dtDate.removeAllItems();
				for(int i = 1; i <= maxDate; ++i)
					dtDate.addItem(i);
            }
		});
		
		int maxDate = VstGuiUtils.getMaxDateForYearAndMonth("1930", "January");
		for(int i = 1; i <= maxDate; ++i)
			dtDate.addItem(i);
		
		JPanel dispathPanel = new JPanel();
		dispathPanel.setLayout(new BoxLayout(dispathPanel, BoxLayout.X_AXIS));
		dispathPanel.add(dtYear);
		dispathPanel.add(dtMonth);
		dispathPanel.add(dtDate);
		
		lDispatchDate = new JLabel("Dispatch Date : ", JLabel.TRAILING);
		lDispatchDate.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		dataPanel.add(lDispatchDate);
		dataPanel.add(dispathPanel);
		// end dispatch date
		
		// start expire date
		xtYear = new JComboBox();
		xtYear.setPreferredSize(new Dimension(100, 25));
        xtYear.setMaximumSize(new Dimension(100, 25));
		xtMonth = new JComboBox(new DateFormatSymbols().getMonths());
		xtMonth.removeItem("");
		xtMonth.setPreferredSize(new Dimension(100, 25));
        xtMonth.setMaximumSize(new Dimension(100, 25));
		xtDate = new JComboBox();
		xtDate.setPreferredSize(new Dimension(80, 25));
        xtDate.setMaximumSize(new Dimension(80, 25));
		
		int xyear = Calendar.getInstance().get(Calendar.YEAR);
		for (int i = xyear; i <= xyear + 50; i++)
			xtYear.addItem(String.valueOf(i));
		
		xtMonth.addActionListener(new ActionListener() {
			@Override
            public void actionPerformed(ActionEvent e) {
				String year = (String)xtYear.getSelectedItem();
                String month = (String)xtMonth.getSelectedItem();
				int maxDate = VstGuiUtils.getMaxDateForYearAndMonth(year, month);
				
				xtDate.removeAllItems();
				for(int i = 1; i <= maxDate; ++i)
					xtDate.addItem(i);
            }
		});
		
		int xmaxDate = VstGuiUtils.getMaxDateForYearAndMonth(String.valueOf(xyear), "January");
		for(int i = 1; i <= xmaxDate; ++i)
			xtDate.addItem(i);
		
		JPanel expPanel = new JPanel();
		expPanel.setLayout(new BoxLayout(expPanel, BoxLayout.X_AXIS));
		expPanel.add(xtYear);
		expPanel.add(xtMonth);
		expPanel.add(xtDate);
		// end expirt date
		
		lExpDate = new JLabel("Expiry Date : ", JLabel.TRAILING);
		lExpDate.setFont(new Font("Monospaced 12", Font.PLAIN, 12));
		dataPanel.add(lExpDate);
		dataPanel.add(expPanel);
		
		SpringUtilities.makeCompactGrid(dataPanel,
                4, 2, //rows, cols
                8, 8, //initialX, initialY
                0, 20);
		
		JPanel basePanel = new JPanel();
        basePanel.setLayout(new BoxLayout(basePanel, BoxLayout.Y_AXIS));
        basePanel.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 10));

        JPanel topPanel = new JPanel(new FlowLayout());
        topPanel.add(lStockTitle);
        topPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, 30));
        topPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 30));
        basePanel.add(topPanel);
        basePanel.add(searchPanel);
		basePanel.add(iPanel);
		//basePanel.add(Box.createRigidArea(new Dimension(10, 10)));
		//JSeparator separator = new JSeparator();
		//separator.setForeground(Color.gray);
		//basePanel.add(separator);
		basePanel.add(dataPanel);
	
		addStock = new JButton("ADD");
		addStock.setPreferredSize(new Dimension(100, 40));
        addStock.setMaximumSize(new Dimension(100, 40));
		updateStock = new JButton("UPDATE");
		updateStock.setPreferredSize(new Dimension(100, 40));
        updateStock.setMaximumSize(new Dimension(100, 40));
		deleteStock = new JButton("DELETE");
		deleteStock.setPreferredSize(new Dimension(100, 40));
        deleteStock.setMaximumSize(new Dimension(100, 40));
		cancel = new JButton("CANCEL");
		cancel.setPreferredSize(new Dimension(100, 40));
        cancel.setMaximumSize(new Dimension(100, 40));
		
		JPanel mainButtonPanel = new JPanel();
		mainButtonPanel.setLayout(new BoxLayout(mainButtonPanel, BoxLayout.X_AXIS));
		mainButtonPanel.add(Box.createHorizontalGlue());
        mainButtonPanel.add(addStock);
        mainButtonPanel.add(updateStock);
		//spacer = Box.createRigidArea(new Dimension(10, 10));
		//mainButtonPanel.add(spacer);
        mainButtonPanel.add(deleteStock);
		mainButtonPanel.add(Box.createRigidArea(new Dimension(10, 10)));
        mainButtonPanel.add(cancel);
		
		basePanel.add(Box.createVerticalGlue());
        basePanel.add(mainButtonPanel);
		
		add(basePanel);
		
		setModalityType(ModalityType.APPLICATION_MODAL);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setMinimumSize(new Dimension(650, 440));
        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((screen.width - 650) / 2, (screen.height - 440) / 2);
	}

	private void initActions() {
		
		addThis.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // search value
            }
        });
		
		advanceSearch.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //
				VstSelectionTableWindow itemSelectionTable = new VstSelectionTableWindow() {
					protected VstTableItemModel installTableModel() {
						java.util.List<VstTableItemSelectable> dataList = itemManagerService.getAllItemsForTable();
						return new VstTableItemModel(dataList, VstGuiConstants.ITEM_COL_NAMES, VstGuiConstants.ITEM_COL_CLASSES);
					}
	
					protected void okButtonClicked() {
						VstTableItemModel tModel = (VstTableItemModel)getModel();
						if (getSelectedRow() == -1)
							return;
					
						VstTableItemSelectable object = tModel.getObjecAtRow(getSelectedRow());
				
						if (object != null) {
							Item item = (Item) object;
							if (item != null) {
								tiCode.setText(item.getItemCode());
								tiName.setText(item.getItemName());
								tiBrand.setText(item.getItemBrand());
								tiCategory.setText(String.valueOf(item.getItemCategoryId()));
								selectedItemId = item.getItemCategoryId();
							}
						}
					}
				};
				itemSelectionTable.setVisible(true);
				//
            }
        });
		
		addStock.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
				if (selectedItemId == -1) {
					JOptionPane.showMessageDialog(null, "Please select an Item", "Critical", JOptionPane.ERROR_MESSAGE);
					return;
				}
				
				Stock stock = getStock();
				stockManagerService.insertStock(stock);
            }
        });
		
		updateStock.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

            }
        });
		
		deleteStock.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                
            }
        });

		cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                close();
            }
        });
	}
	
	public Stock getStock() {
		Stock stock = new Stock();
	
		stock.setPurchaseOrderId("");
		
		int dyear = Integer.parseInt((String) dtYear.getSelectedItem());
		int dmonth = VstGuiUtils.getMonthValue((String) dtMonth.getSelectedItem());
		assert (dmonth != -1);
		int dday = (Integer) dtDate.getSelectedItem();
		
		if (dmonth != -1 && dmonth < 12 && dday > 0 && dday < 32 && dyear > 1900) {
			Date dispatchdate = DateTimeUtils.getDateFromISO8601String(dyear + "-" + dmonth + "-" + dday);
			stock.setDispachedDate(dispatchdate);
		}
		
		stock.setPurchasedPrice(100f);
		
		float qty = ((Number)tQty.getValue()).floatValue();
		stock.setQuantity(qty);
		
		JFormattedTextField unitp = getTextField(tunitPrice);
		JFormattedTextField minp = getTextField(tminPrice);
		JFormattedTextField maxp = getTextField(tmaxPrice);
		JFormattedTextField discount = getTextField(tDiscount);
		
		stock.setUnitPrice(((Number)unitp.getValue()).floatValue());
		stock.setMinPrice(((Number)minp.getValue()).floatValue());
		stock.setMaxPrice(((Number)maxp.getValue()).floatValue());
		stock.setDiscount(((Number)discount.getValue()).floatValue());
		
		int xyear = Integer.parseInt((String) xtYear.getSelectedItem());
		int xmonth = VstGuiUtils.getMonthValue((String) xtMonth.getSelectedItem());
		assert (xmonth != -1);
		int xday = (Integer) xtDate.getSelectedItem();
		
		if (xmonth != -1 && xmonth < 12 && xday > 0 && xday < 32 && xyear > 1900) {
			Date expdate = DateTimeUtils.getDateFromISO8601String(xyear + "-" + xmonth + "-" + xday);
			stock.setExpiryDate(expdate);
		}

		stock.setItemId(selectedItemId);
		return stock;
	}
	
	private JFormattedTextField getTextField(JSpinner spinner) {
		JComponent editor = spinner.getEditor();
		if (editor instanceof JSpinner.DefaultEditor) {
			return ((JSpinner.DefaultEditor)editor).getTextField();
		} else {
			System.err.println("ERROR : JSpinner error in VstStockDataForm");
			return null;
		}
	}
	
	public void populate(Stock stock) {
		if (stock == null)
			return;
		
		currentStockId = stock.getStockId();
		
		Item item = itemManagerService.getItemById(stock.getItemId());
		selectedItemId = item.getItemId();
		
		tiCode.setText(item.getItemCode());
		tiName.setText(item.getItemName());
		tiBrand.setText(item.getItemBrand());
		tiCategory.setText(String.valueOf(item.getItemCategoryId()));
		
		tunitPrice.setValue(stock.getUnitPrice());
		tminPrice.setValue(stock.getMinPrice());
		tmaxPrice.setValue(stock.getMaxPrice());
		tDiscount.setValue(stock.getDiscount());
		tQty.setValue(stock.getQuantity());

		Calendar cal = Calendar.getInstance();
		
		Date ddate = stock.getDispachedDate();
		if (ddate != null) {
			cal.setTime(ddate);
			int yName = cal.get(Calendar.YEAR);
			dtYear.setSelectedItem(String.valueOf(yName));
			String mName = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH);
			dtMonth.setSelectedItem(mName);
		}
		
		Date xdate = stock.getExpiryDate();
		if (xdate != null) {
			cal.setTime(xdate);
			int yName = cal.get(Calendar.YEAR);
			xtYear.setSelectedItem(String.valueOf(yName));
			String mName = cal.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.ENGLISH);
			xtMonth.setSelectedItem(mName);
		}
	}
	
	private void close() {
        dispose();
    }
	
}